#include "debug.h"

#define     DEBUG_GPIO_PORT         GPIOB
#define     DEBUG_GPIO_TX_PIN       GPIO_Pin_6
#define     DEBUG_GPIO_RX_PIN       GPIO_Pin_7
#define     DEBUG_PIN_SOURCE_TX     GPIO_PinSource6
#define     DEBUG_PIN_SOURCE_RX     GPIO_PinSource7

rx_callback_t ex_recv;

// 标准库需要的支持函数（避免半主机模式）
#pragma import(__use_no_semihosting)

struct __FILE
{
    int handle;
};

FILE __stdout;

void _sys_exit(int x)
{ 
    x = x;
}

// 重定向fputc函数（用于printf输出到串口）
int fputc(int ch, FILE *f)
{
    while((USART1->SR & 0X40) == 0); // 等待发送完成
    USART1->DR = (uint8_t)ch;
    return ch;
}

void debug_init(uint32_t bound_rate)
{
    // GPIO端口初始化
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // 使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 使能USART1时钟
 
    // 配置PA9为USART1_TX，PA10为USART1_RX
    GPIO_PinAFConfig(DEBUG_GPIO_PORT, DEBUG_PIN_SOURCE_TX, GPIO_AF_USART1);
    GPIO_PinAFConfig(DEBUG_GPIO_PORT, DEBUG_PIN_SOURCE_RX, GPIO_AF_USART1);

    // 初始化PA9、PA10为复用推挽上拉
    GPIO_InitStructure.GPIO_Pin    = DEBUG_GPIO_TX_PIN | DEBUG_GPIO_RX_PIN;
    GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType  = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd   = GPIO_PuPd_UP;
    GPIO_Init(DEBUG_GPIO_PORT, &GPIO_InitStructure);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能USART1接收中断

    // USART1参数配置
    USART_InitStructure.USART_BaudRate              = bound_rate;
    USART_InitStructure.USART_WordLength            = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits              = USART_StopBits_1;
    USART_InitStructure.USART_Parity                = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl   = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                  = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
}

// 发送一个字节到USART1
void usart_sendbyte(uint8_t data)
{
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
    USART_SendData(USART1, data);
}

// 注册串口接收回调
void usart_recv_register(rx_callback_t callback)
{
    ex_recv = callback;
}

// USART1中断服务函数
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        uint8_t data = USART_ReceiveData(USART1);
        if(ex_recv != NULL)
        {
            ex_recv(data);
        }
    }
}
